package org.jing.core.util;

import org.jing.core.lang.JingException;
import org.jing.core.lang.data.Pair2;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import static java.lang.Thread.currentThread;

/**
 * Description: <br>
 *
 * @author bks <br>
 * @since 2019-03-21 <br>
 */
@SuppressWarnings({ "WeakerAccess", "unused", "Duplicates", "rawtypes" })
public class ClassUtil {
    private static final ConcurrentHashMap<Class<?>, List<Field>> ALL_FIELDS_MAP = new ConcurrentHashMap<>();

    private static ClassLoader defaultClassLoader;

    private static final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

    /**
     * Description: 判断是否为"基础"类型. <br>
     * <b>Byte</b>/<b>Short</b>/<b>Integer</b>/<b>Long</b>/<b>Float</b>/<b>Double</b>/<b>Character</b>/<b>Boolean</b>/
     * <b>String</b>/<b>BigDecimal</b>/<b>BigInteger</b>/<b>Class</b> <br>
     *
     * @param type <br>
     * @return <br>
     */
    public static boolean isBasicType(Class type) {
        return byte.class == type || Byte.class == type || short.class == type || Short.class == type || int.class == type || Integer.class == type
            || long.class == type || Long.class == type || float.class == type || Float.class == type || double.class == type || Double.class == type
            || char.class == type || Character.class == type || boolean.class == type || Boolean.class == type
            || String.class == type  || BigDecimal.class == type || BigInteger.class == type || Class.class == type;
    }

    /**
     * Description: 判断是否为直观的数字类型. <br>
     * <b>BigDecimal</b>/<b>BigInteger</b>/<b>Byte</b>/<b>Short</b>/<b>Integer</b>/<b>Long</b>/<b>Float</b>/<b>Double</b> <br>
     *
     * @param object 对象 <br>
     * @return <br>
     */
    public static boolean isNumber(Object object) {
        if (null == object) return false;
        return object instanceof Byte || object instanceof Short || object instanceof Integer || object instanceof Long
            || object instanceof Float || object instanceof Double || object instanceof BigDecimal || object instanceof BigInteger;
    }

    /**
     * Description: 转换成数值类型. <br>
     * <b>BigDecimal</b>/<b>BigInteger</b>/<b>Byte</b>/<b>Short</b>/<b>Integer</b>/<b>Long</b>/<b>Float</b>/<b>Double</b>/<b>String</b> <br>
     *
     * @param value 对象 <br>
     * @throws JingException 转换失败 <br>
     * @return BigDecimal <br>
     */
    public static BigDecimal cast2Number(Object value) {
        if (null == value) {
            return null;
        }
        else if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        else if (value instanceof BigInteger) {
            return new BigDecimal((BigInteger) value);
        }
        else if (value instanceof Byte) {
            return BigDecimal.valueOf((byte) value);
        }
        else if (value instanceof Short) {
            return BigDecimal.valueOf((short) value);
        }
        else if (value instanceof Integer) {
            return BigDecimal.valueOf((int) value);
        }
        else if (value instanceof Long) {
            return BigDecimal.valueOf((long) value);
        }
        else if (value instanceof Float) {
            return BigDecimal.valueOf((float) value);
        }
        else if (value instanceof Double) {
            return BigDecimal.valueOf((double) value);
        }
        else if (value instanceof String) {
            return new BigDecimal((String) value);
        }
        else {
            throw new NumberFormatException();
        }
    }

    /**
     * Description: 转换成布尔值类型. <br>
     * <b>true</b>/<b>false</b>/<b>"true"</b>/<b>"false"</b> <br>
     *
     * @param value 对象 <br>
     * @throws JingException 转换失败 <br>
     * @return boolean <br>
     */
    public static boolean cast2Boolean(Object value) {
        if (value instanceof Boolean) {
            return (boolean) value;
        }
        else if (value instanceof String) {
            String val = (String) value;
            if ("true".equalsIgnoreCase(val)) {
                return true;
            }
            else if ("false".equalsIgnoreCase(val)) {
                return false;
            }
        }
        throw new JingException("invalid boolean format");
    }

    /**
     * Description: 转换成字符串类型. <br>
     *
     * @param value 对象 <br>
     * @throws JingException 转换失败 <br>
     * @return String <br>
     */
    public static String cast2String(Object value) {
        if (null == value || value instanceof String) {
            return (String) value;
        }
        else if (value instanceof Float || value instanceof Double) {
            return BigDecimal.valueOf((Double) value).toString();
        }
        else {
            try {
                return String.valueOf(value);
            }
            catch (Throwable t) {
                try {
                    return value.toString();
                }
                catch (Throwable t$) {
                    throw new JingException("failed to cast to string");
                }
            }
        }
    }

    /**
     * Description: 根据输入类, 按照指定规则获取其类加载器调用优先链. <br>
     * 当前类的
     *
     * @param clazz 类 <br>
     * @return <br>
     */
    public static ClassLoader[] getClassLoader(Class<?> clazz) {
        return new ClassLoader[] { null == clazz ? null : clazz.getClassLoader(), defaultClassLoader,
            currentThread().getContextClassLoader(), ClassUtil.class.getClassLoader(), systemClassLoader
        };
    }

    /**
     * Description: 根据按照指定规则获取其类加载器调用优先链. <br>
     *
     * @return <br>
     */
    public static ClassLoader[] getClassLoader() {
        return getClassLoader(null);
    }

    /**
     * Description: 加载类并返回. <br>
     *
     * @param className 类名 <br>
     * @param loader 加载器 <br>
     * @return <br>
     * @throws JingException 加载失败 <br>
     */
    public static Class<?> loadClass(String className, ClassLoader loader) {
        try {
            if (null != loader && !StringUtil.isEmpty(className)) {
                return loader.loadClass(className);
            }
            return null;
        }
        catch (Throwable t) {
            throw new JingException(t, "failed to load class [{}] by [{}]", className, loader);
        }
    }

    /**
     * Description: 加载类并返回. <br>
     *
     * @param className 类名 <br>
     * @param loaders 加载器数组 <br>
     * @return <br>
     * @throws JingException 加载失败 <br>
     */
    public static Class<?> loadClass(String className, ClassLoader[] loaders) {
        if (null != loaders && !StringUtil.isEmpty(className)) {
            int count = loaders.length;
            for (ClassLoader loader$ : loaders) {
                if (null != loader$) {
                    try {
                        Class<?> clazz = loadClass(className, loader$);
                        if (null != clazz) {
                            return clazz;
                        }
                    }
                    catch (Throwable ignored) {
                    }
                }
            }
        }
        return null;
    }

    /**
     * Description: 使用一定规则生成的加载器集合依次尝试加载类并返回. <br>
     *
     * @param className 类名 <br>
     * @return <br>
     * @throws JingException 加载失败 <br>
     */
    public static Class<?> loadClass(String className) {
        return loadClass(className, getClassLoader(ClassUtil.class));
    }

    /**
     * Description: 根据文件列举出所有类. <br>
     *
     * @param pkgName 包名 <br>
     * @param pkgPath 包路径 <br>
     * @param classes 操作集合 <br>
     */
    private static void findClassesByFile(String pkgName, String pkgPath, Set<Class<?>> classes) {
        // 获取此包的目录 建立一个File
        File dir = new File(pkgPath);
        // 如果不存在或者 也不是目录就直接返回
        if (!dir.exists() || !dir.isDirectory()) {
            return;
        }
        File[] files = dir.listFiles(pathName -> pathName.isDirectory() || pathName.getName().endsWith("class"));

        if (null == files || files.length == 0) {
            return;
        }

        String className;
        Class clz;
        // 循环所有文件
        for (File f : files) {
            // 如果是目录 则继续扫描
            if (f.isDirectory()) {
                findClassesByFile(pkgName + "." + f.getName(), pkgPath + "/" + f.getName(), classes);
                continue;
            }
            // 如果是java类文件 去掉后面的.class 只留下类名
            className = f.getName();
            className = className.substring(0, className.length() - 6);

            //加载类
            clz = loadClass(pkgName + "." + className);
            // 添加到集合中去
            if (clz != null) {
                classes.add(clz);
            }
        }
    }

    /**
     * Description: 把jar包里指定包路径下的类都加载进集合内. <br>
     *
     * @param pkgName 包路径 <br>
     * @param jar jar包 <br>
     * @param classes 操作集合 <br>
     * @throws JingException <br>
     */
    public static void findClassesByJar(String pkgName, JarFile jar, Set<Class<?>> classes) {
        String pkgDir = pkgName.replace(".", "/");
        // 从此jar包 得到一个枚举类
        Enumeration<JarEntry> entry = jar.entries();

        JarEntry jarEntry;
        String name, className;
        Class<?> clazz;
        // 同样地进行循环迭代
        while (entry.hasMoreElements()) {
            // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文
            jarEntry = entry.nextElement();

            name = jarEntry.getName();
            // 如果是以/开头的
            if (name.charAt(0) == '/') {
                // 获取后面的字符串
                name = name.substring(1);
            }

            if (jarEntry.isDirectory() || !name.startsWith(pkgDir) || !name.endsWith(".class")) {
                continue;
            }
            //如果是一个.class文件 而且不是目录
            // 去掉后面的".class" 获取真正的类名
            className = name.substring(0, name.length() - 6);
            //加载类
            clazz = loadClass(className.replace("/", "."));
            // 添加到集合中去
            if (clazz != null) {
                classes.add(clazz);
            }
        }
    }

    /**
     * Description: 扫描包路径下所有的类. <br>
     *
     * @param packagePath 包路径 <br>
     * @return <br>
     */
    public static Set<Class<?>> getClassByPackage(String packagePath) {
        //第一个class类的集合
        Set<Class<?>> classes = new HashSet<>();
        // 获取包的名字 并进行替换
        String pkgDirName = packagePath.replace('.', '/');
        ClassLoader[] loaders = getClassLoader(ClassUtil.class);
        try {
            for (ClassLoader loader$ : loaders) {
                if (null == loader$) {
                    continue;
                }
                Enumeration<URL> urls = loader$.getResources(pkgDirName);
                if (null == urls) {
                    continue;
                }
                while (urls.hasMoreElements()) {
                    URL url = urls.nextElement();
                    // 得到协议的名称
                    String protocol = url.getProtocol();
                    // 如果是以文件的形式保存在服务器上
                    if ("file".equals(protocol)) {
                        // 获取包的物理路径
                        String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                        // 以文件的方式扫描整个包下的文件 并添加到集合中
                        findClassesByFile(packagePath, filePath, classes);
                    } else if ("jar".equals(protocol)) {
                        // 如果是jar包文件
                        // 获取jar
                        JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile();
                        //扫描jar包文件 并添加到集合中
                        findClassesByJar(packagePath, jar, classes);
                    }
                }
            }
        } catch (IOException e) {
            throw new JingException(e, "failed to get class [packagePath: {}]", packagePath);
        }

        return classes;
    }

    /**
     * Description: 获取包路径下所有实现了指定接口的类. <br>
     *
     * @param packagePath 包路径 <br>
     * @param interfaceType 指定接口 <br>
     * @param <T> <br>
     * @return <br>
     */
    public static <T> Set<Class<? super T>> getClassByPackage(String packagePath, Class<T> interfaceType) {
        if (null == interfaceType) throw new JingException("interface required");
        Set<Class<?>> classes = getClassByPackage(packagePath);
        Set<Class<? super T>> retSet = new HashSet<>();
        for (Class<?> clazz : classes) {
            if (Arrays.asList(clazz.getGenericInterfaces()).contains(interfaceType)) {
                retSet.add((Class<? super T>) clazz);
            }
        }
        return retSet;
    }

    /**
     * Description: 判断属性是否为静态属性. <br>
     *
     * @param field 属性 <br>
     * @return <br>
     */
    public static boolean isFieldStatic(Field field) {
        return Modifier.isStatic(field.getModifiers());
    }

    /**
     * Description: 判断方法是否为静态方法. <br>
     *
     * @param method 方法 <br>
     * @return <br>
     */
    public static boolean isMethodStatic(Method method) {
        return Modifier.isStatic(method.getModifiers());
    }

    /**
     * Description: 获取所有属性 <br>
     * 包含父类的 <br>
     *
     * @param clazz 类 <br>
     * @return <br>
     */
    public static List<Field> getFields(Class<?> clazz) {
        List<Field> fields;
        if (null == (fields = ALL_FIELDS_MAP.get(clazz))) {
            synchronized (ALL_FIELDS_MAP) {
                if (null == (fields = ALL_FIELDS_MAP.get(clazz))) {
                    fields = new ArrayList<>();
                    HashSet<String> fieldNameSet = new HashSet<>();
                    Class<?> c$ = clazz;
                    String filedName;
                    while (null != c$) {
                        Field[] fArr = c$.getDeclaredFields();
                        for (int i$ = GenericUtil.count(fArr) - 1; i$ >= 0; i$ --) {
                            // 子类属性覆盖父类属性
                            if (fieldNameSet.contains(filedName = fArr[i$].getName())) {
                                continue;
                            }
                            fields.add(0, fArr[i$]);
                            fieldNameSet.add(filedName);
                        }
                        c$ = c$.getSuperclass();
                    }
                    ALL_FIELDS_MAP.put(clazz, fields);
                }
            }
        }
        return fields;
    }

    /**
     * Description: 获取指定类的和指定类型有关系的所有类. <br>
     *
     * @param clazz 指定类 <br>
     * @param relation 指定关系类型, 为空则不过滤 <br>
     * @return <br>
     */
    public static List<Field> getFields(Class clazz, Class relation) {
        List<Field> fields = getFields(clazz);
        List<Field> retList = new ArrayList<>();
        GenericUtil.loop(fields, f$ -> {
            if (null == relation || relation.isAssignableFrom(f$.getType())) {
                retList.add(f$);
            }
        });
        return retList;
    }

    /**
     * Description: 根据属性名获取属性. <br>
     *
     * @param object 对象 <br>
     * @param name 属性名 <br>
     * @return <br>
     */
    public static Field getField(Object object, String name) {
        List<Field> fields = getFields(object.getClass());
        for (Field f$ : fields) {
            if (f$.getName().equals(name)) {
                return f$;
            }
        }
        return null;
    }

    /**
     * Description: 根据属性名获取属性. <br>
     *
     * @param clazz 类 <br>
     * @param name 属性名 <br>
     * @return <br>
     */
    public static Field getField(Class clazz, String name) {
        List<Field> fields = getFields(clazz);
        for (Field f$ : fields) {
            if (f$.getName().equals(name)) {
                return f$;
            }
        }
        return null;
    }

    /**
     * Description: 根据属性名获取属性的值. <br>
     * 这种方式只能获取静态属性的值. <br>
     *
     * @param clazz 类 <br>
     * @param name 属性名 <br>
     * @return <br>
     */
    public static Object getFieldValue(Class clazz, String name) {
        Field field = getField(clazz, name);
        if (null == field) throw new JingException("field {} not found", name);
        field.setAccessible(true);
        if (!isFieldStatic(field)) {
            throw new JingException("only static field can be operated");
        }
        try {
            return field.get(null);
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 根据实例获取属性的值. <br>
     *
     * @param object 实例 <br>
     * @param field 属性 <br>
     * @return <br>
     */
    public static Object getFieldValue(Object object, Field field) {
        try {
            field.setAccessible(true);
            if (isFieldStatic(field)) {
                return field.get(null);
            }
            else {
                return field.get(object);
            }
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 根据实例和属性名获取属性的值. <br>
     *
     * @param object 实例 <br>
     * @param name 属性名 <br>
     * @return <br>
     */
    public static Object getFieldValue(Object object, String name) {
        Field field = getField(object, name);
        if (null == field) throw new JingException("field {} not found", name);
        return getFieldValue(object, field);
    }

    /**
     * Description: 设置属性的值. <br>
     * 这种方式只能设置静态属性的值. <br>
     *
     * @param field 属性 <br>
     * @param value 属性值 <br>
     */
    public static void setFieldValue(Field field, Object value) {
        field.setAccessible(true);
        if (!isFieldStatic(field)) {
            throw new JingException("only static field can be operated");
        }
        try {
            field.set(null, value);
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 根据属性名设置属性的值. <br>
     * 这种方式只能设置静态属性的值. <br>
     *
     * @param clazz 类 <br>
     * @param name 属性名 <br>
     * @param value 属性值 <br>
     */
    public static void setFieldValue(Class clazz, String name, Object value) {
        Field field = getField(clazz, name);
        if (null == field) throw new JingException("filed {} not found", name);
        setFieldValue(field, value);
    }

    /**
     * Description: 根据实例设置属性的值. <br>
     *
     * @param object 实例 <br>
     * @param field 属性 <br>
     * @param value 属性值 <br>
     */
    public static void setFieldValue(Object object, Field field, Object value) {
        try {
            field.setAccessible(true);
            if (isFieldStatic(field)) {
                field.set(null, value);
            }
            else {
                field.set(object, value);
            }
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 根据实例和属性名获取属性的值. <br>
     *
     * @param object 实例 <br>
     * @param name 属性名 <br>
     * @param value 属性值 <br>
     */
    public static void setFieldValue(Object object, String name, Object value) {
        Field field = getField(object, name);
        if (null == field) throw new JingException("field {} not found", name);
        setFieldValue(object, field, value);
    }

    /**
     * Description: 根据类和入参创建实例. <br>
     *
     * @param clazz 指定类 <br>
     * @param parameters 入参 <br>
     * @param <T> <br>
     * @param <V> <br>
     * @return <br>
     */
    @SafeVarargs
    public static <T, V> T createInstance(Class<T> clazz, Pair2<Class<V>, V>... parameters) {
        try {
            int count = GenericUtil.count(parameters);
            Class<?>[] tA = new Class[count];
            Object[] oA = new Object[count];
            GenericUtil.loop(parameters, (i$, p$) -> {
                tA[i$] = p$.getA();
                oA[i$] = p$.getB();
            });
            Constructor<T> constructor = clazz.getDeclaredConstructor(tA);
            constructor.setAccessible(true);
            return constructor.newInstance(oA);
        }
        catch (JingException e) {
            throw e;
        }
        catch (Throwable t) {
            throw new JingException(t, "failed to serialize instance for class [{}]", clazz.getName());
        }
    }

    /**
     * Description: 执行方法. <br>
     * 只能执行静态方法. <br>
     *
     * @param method 方法 <br>
     * @param parameters 参数 <br>
     * @param <T> <br>
     * @return <br>
     */
    public static <T> Object executeMethod(Method method, Object... parameters) {
        if (!isMethodStatic(method)) {
            throw new JingException("only static method can be operated");
        }
        try {
            method.setAccessible(true);
            return method.invoke(null, parameters);
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 执行方法. <br>
     * 只能执行静态方法. <br>
     *
     * @param clazz 类 <br>
     * @param name 方法名 <br>
     * @param parameters 参数(类型,值) <br>
     * @param <T> <br>
     * @return <br>
     */
    @SafeVarargs
    public static <T> Object executeMethod(Class clazz, String name, Pair2<Class<T>, T>... parameters) {
        int count = GenericUtil.count(parameters);
        Class<?>[] tA = new Class[count];
        Object[] oA = new Object[count];
        GenericUtil.loop(parameters, (i$, p$) -> {
            tA[i$] = p$.getA();
            oA[i$] = p$.getB();
        });
        try {
            Method method = clazz.getDeclaredMethod(name, tA);
            return executeMethod(method, oA);
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 执行方法. <br>
     *
     * @param object 实例 <br>
     * @param method 方法 <br>
     * @param parameters 参数 <br>
     * @param <T> <br>
     * @return <br>
     */
    public static <T> Object executeMethod(Object object, Method method, Object... parameters) {
        try {
            method.setAccessible(true);
            if (isMethodStatic(method)) {
                return method.invoke(object.getClass(), parameters);
            }
            else {
                return method.invoke(object, parameters);
            }
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 执行方法. <br>
     *
     * @param object 实例 <br>
     * @param name 方法名 <br>
     * @param parameters 参数(类型,值) <br>
     * @param <T> <br>
     * @return <br>
     */
    @SafeVarargs
    public static <T> Object executeMethod(Object object, String name, Pair2<Class<T>, T>... parameters) {
        int count = GenericUtil.count(parameters);
        Class<?>[] tA = new Class[count];
        Object[] oA = new Object[count];
        GenericUtil.loop(parameters, (i$, p$) -> {
            tA[i$] = p$.getA();
            oA[i$] = p$.getB();
        });
        try {
            Method method = object.getClass().getDeclaredMethod(name, tA);
            return executeMethod(object, method, oA);
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 获取反射的注解, 如果没有获取到会报错. <br>
     *
     * @param reflect 反射 <br>
     * @param annotation 注解 <br>
     * @param <T> <br>
     * @return <br>
     */
    public static <T> T getAnnotationWithException(Object reflect, Class<T> annotation) {
        T t = (T) executeMethod(reflect, "getAnnotation", new Pair2<>(Class.class, annotation));
        if (null == t) {
            throw new JingException("type {} must be annotated by {}", reflect, annotation.getSimpleName());
        }
        return t;
    }

    /**
     * Description: 强转设置指定实例的属性. <br>
     *
     * @param instance 实例 <br>
     * @param field 属性 <br>
     * @param value 值 <br>
     * @return true:成功/false:失败 <br>
     */
    public static boolean cast(Object instance, Field field, Object value) {
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }
        Class fieldType = field.getType();
        try {
            field.set(instance, value);
            return true;
        }
        catch (Throwable ignored) {}
        if (isBasicType(fieldType)) {
            try {
                field.set(instance, cast(fieldType, value));
                return true;
            }
            catch (Throwable ignored) {}
        }
        return false;
    }

    /**
     * Description: 先转成字符串再强转设置变量 <br>
     * 只处理基础变量以及BigDecimal/BigInteger/String/Class <br>
     *
     * @param type 类型 <br>
     * @param object 值 <br>
     * @return <br>
     */
    public static <T> T cast(Class<T> type, Object object) {
        String value = cast2String(object);
        if (type == String.class) {
            return (T) value;
        }
        else if (type == byte.class || type == Byte.class) {
            return (T) (Byte) StringUtil.parseByte(value);
        }
        else if (type == short.class || type == Short.class) {
            return (T) (Short) StringUtil.parseShort(value);
        }
        else if (type == int.class || type == Integer.class) {
            return (T) (Integer) StringUtil.parseInteger(value);
        }
        else if (type == long.class || type == Long.class) {
            return (T) (Long) StringUtil.parseLong(value);
        }
        else if (type == float.class || type == Float.class) {
            return (T) (Float) StringUtil.parseFloat(value);
        }
        else if (type == double.class || type == Double.class) {
            return (T) (Double) StringUtil.parseDouble(value);
        }
        else if (type == boolean.class || type == Boolean.class) {
            return (T) ((Boolean) ("Y".equalsIgnoreCase(value) || "YES".equalsIgnoreCase(value) || "TRUE".equalsIgnoreCase(value)));
        }
        else if (type == BigDecimal.class) {
            return (T) new BigDecimal(StringUtil.ifEmpty(value, "0"));
        }
        else if (type == BigInteger.class) {
            return (T) new BigInteger(StringUtil.ifEmpty(value, "0"));
        }
        else if (type == Class.class) {
            try {
                return (T) Class.forName(value);
            }
            catch (Throwable t) {
                throw new JingException(t, "parse error");
            }
        }
        else {
            throw new JingException("parse error");
        }
    }

    /**
     * Description: 找到指定父类. <br>
     * 用于明确父类的实际泛型. <br>
     *
     * @param type 类 <br>
     * @param target 父类 <br>
     * @return <br>
     */
    public static Class findSuperClass(Class type, Class target) {
        Class before = type, after;
        while (null != (after = before.getSuperclass())) {
            if (after == target) {
                return before;
            }
            else {
                before = after;
            }
        }
        return null;
    }

    private static <T> Pair2<Class[], Object[]> generateParameters(Pair2<Class<T>, T>[] parameters) {
        int count = GenericUtil.count(parameters);
        Class<?>[] tA = new Class[count];
        Object[] oA = new Object[count];
        GenericUtil.loop(parameters, (i$, p$) -> {
            tA[i$] = p$.getA();
            oA[i$] = p$.getB();
        });
        return new Pair2<>(tA, oA);
    }
}